import React, { Component, PropTypes } from 'react'
import { Modal, Icon, Spin, Tooltip } from 'antd'
import Invoice from "containers/my-account/invoice";
import financeAuditService from '../../finance-audit.service'
import { EventUtils, messages } from 'share/common'
import ReceiptAmountMsg from '../../../../my-account/components/receipt-amount-msg';

class SlideExpenseReportDetailExpenseInvoiceSummaryItem extends Component {

  state = {
    loading: false
  };

  check = () => {
    const { invoice, onCheck, disabled } = this.props;
    const { loading } = this.state;
    if(!loading && !disabled) {
      this.setState({ loading: true });
      financeAuditService.checkInvoice({
        receiptID: invoice.id,
        checked: !invoice.checked
      }).then(() => {
        onCheck(!invoice.checked, invoice.id)
      }).finally(() => {
        this.setState({ loading: false })
      })
    }
  };

  handleShowUsedMsg = (receipt) => {
    ReceiptAmountMsg.open({
      receiptId: receipt.id,
      invoiceOID: receipt.invoiceOID,
    }, this);
  };

  render() {
    const { invoice, selected } = this.props;
    const { loading } = this.state;
    return (
      <Spin spinning={loading}>
        <div className={this.classNames([
          'invoice-container',
          { 'selected': selected }
        ])}>
          <Invoice
            invoiceList={[invoice]}
            disabledEdit
            showUsedMsg={(invoice, index) => this.handleShowUsedMsg(invoice, index)}
          />
          <Icon
            className='check-icon'
            type={invoice.checked ? "check-circle" : "question-circle"}
            onClick={this.check}
          />
        </div>
      </Spin>
    )
  }
}

class SlideExpenseReportDetailExpenseInvoiceSummaryFrame extends Component {

  refList = {};

  state = {
    receiptList: [],
    groupIndex: 0,
    receiptIndex: 0
  };

  componentDidMount() {
    const { receiptList } = this.props;
    this.setState({ receiptList });
    EventUtils.addHandler(document, 'keyup', this.onKeyUp);
  }

  componentWillUnmount() {
    EventUtils.removeHandler(document, 'keyup', this.onKeyUp);
  }

  resetScroll = () => {
    let { groupIndex, receiptIndex } = this.state;
    let groupDOM = document.getElementsByClassName('slide-expense-report-detail-expense-invoice-summary-frame-group')[groupIndex];
    let receiptDOM = groupDOM.getElementsByClassName('invoice-container')[receiptIndex];
    let receiptRect = receiptDOM.getBoundingClientRect();
    let scrollDOM = document.getElementsByClassName('slide-expense-report-detail-expense-invoice-summary-frame')[0];
    let scrollRect = scrollDOM.getBoundingClientRect();
    let offsetTop = receiptRect.top - scrollRect.top;
    let offsetBottom = offsetTop + receiptRect.height - scrollRect.height;
    if(offsetBottom > 0) {
      scrollDOM.scrollTop += offsetBottom + 20;
    }
    if(offsetTop < 0) {
      scrollDOM.scrollTop += offsetTop - 50;
    }
    let offsetLeft = receiptRect.left - scrollRect.left;
    let offsetRight = offsetLeft + receiptRect.width - scrollRect.width;
    if(offsetRight > 0) {
      scrollDOM.scrollLeft += offsetRight + 20;
    }
    if(offsetLeft < 0) {
      scrollDOM.scrollLeft += offsetLeft - 20;
    }
  };

  static contextTypes = {
    isWaitForAudit: PropTypes.bool
  };

  onKeyUp = e => {
    e.stopPropagation();
    let { groupIndex, receiptIndex, receiptList } = this.state;
    const { isWaitForAudit } = this.context;
    let group = this.getReceiptGroup(receiptList);
    let groupList = Object.keys(group);
    let list = group[groupList[groupIndex]].list;
    let keyCode = e.keyCode || e.which || e.charCode;
    switch(keyCode) {
      //空格
      case 32: {
        if(isWaitForAudit) {
          let nowInvoiceId = list[receiptIndex].id;
          if(this.refList[nowInvoiceId]) {
            this.refList[nowInvoiceId].check();
          }
        }
        break;
      }
      //⬅
      case 37: {
        if(groupIndex !== 0) {
          groupIndex--;
          list = group[groupList[groupIndex]].list;
          if(!list[receiptIndex]) {
            receiptIndex = list.length - 1;
          }
          this.setState({ receiptIndex, groupIndex }, this.resetScroll);
        }
        break;
      }
      //⬆
      case 38:{
        if(receiptIndex !== 0) {
          this.setState({ receiptIndex: --receiptIndex }, this.resetScroll);
        }
        break;
      }
      //➡
      case 39:{
        if(groupIndex !== groupList.length - 1) {
          groupIndex++;
          list = group[groupList[groupIndex]].list;
          if(!list[receiptIndex]) {
            receiptIndex = list.length - 1;
          }
          this.setState({ receiptIndex, groupIndex }, this.resetScroll);
        }
        break;
      }
      //⬇
      case 40:{
        if(receiptIndex !== list.length - 1) {
          this.setState({ receiptIndex: ++receiptIndex }, this.resetScroll);
        }
        break;
      }
    }
  };

  getReceiptGroup = receiptList => {
    let group = {};
    receiptList.map(receipt => {
      if(!group[receipt.invoiceTypeNo]) {
        group[receipt.invoiceTypeNo] = {
          list: [],
          type: receipt.type
        }
      }
      group[receipt.invoiceTypeNo].list.push(receipt)
    });
    return group;
  };

  onCheck = (checked, id) => {
    const { receiptList } = this.state;
    const { onCheck } = this.props;
    receiptList.forEach(receipt => {
      if(receipt.id === id)
        receipt.checked = checked;
      return receipt;
    });
    this.setState({ receiptList });
    let checkedNumber = receiptList.filter(receipt => receipt.checked).length;
    onCheck(checkedNumber);
  };

  render() {
    const { receiptList, groupIndex, receiptIndex } = this.state;
    let group = this.getReceiptGroup(receiptList);
    const { isWaitForAudit } = this.context;
    return (
      <div className='slide-expense-report-detail-expense-invoice-summary-frame'>
        {Object.keys(group).map((key, gI) => (
          <div className='slide-expense-report-detail-expense-invoice-summary-frame-group' key={key}>
            <h4>{group[key].type}({group[key].list.length})</h4>
            {group[key].list.map((invoice, rI) => <SlideExpenseReportDetailExpenseInvoiceSummaryItem
              invoice={invoice}
              key={invoice.id}
              selected={gI === groupIndex && rI === receiptIndex}
              onCheck={this.onCheck}
              ref={item => this.refList[invoice.id] = item}
              disabled={!isWaitForAudit}
            />)}
          </div>
        ))}
      </div>
    )
  }
}

class SlideExpenseReportDetailExpenseInvoiceSummary extends Component {

  state = {
    visible: false,
    checkedNumber: 0
  };

  componentDidMount() {
    this.getCheckedNumber(this.props.receiptList);
  }

  componentWillReceiveProps(nextProps) {
    this.getCheckedNumber(nextProps.receiptList);
  }

  getCheckedNumber = receiptList => {
    let checkedNumber = receiptList.filter(receipt => receipt.checked).length;
    this.onCheck(checkedNumber);
  };

  onCheck = checkedNumber => {
    this.setState({ checkedNumber });
  };

  static contextTypes = {
    isWaitForAudit: PropTypes.bool
  };

  renderTitle = () => {
    const { receiptList } = this.props;
    const { checkedNumber } = this.state;
    const { isWaitForAudit } = this.context;
    const infoContent = (
      <div>
        {messages('expense-14.key273')/*1. 此模式下显示单据内所有发票；*/}<br/>
        {messages('expense-14.key274')/*2. 通过键盘↔️、↕️可以切换发票*/}
        {isWaitForAudit ? messages('expense-14.key275')/*，按【空格】标记已核对/未核对.*/ : '.'}<br/>
        {isWaitForAudit && messages('expense-14.key276')/*3. 通过鼠标也可以直接点击发票右上角的 ?/X 来进行核对操作。*/}
      </div>
    );
    return (
      <span className='slide-expense-report-detail-expense-invoice-summary-modal-title'>
        {messages('expense-14.key277')/*发票概览*/}
        <Tooltip title={infoContent} placement="bottomLeft">
          <Icon type="info-circle" />
        </Tooltip>
        <Icon type='check-circle'/>&nbsp;{messages('expense-14.key17')/*已核对*/}({checkedNumber})
        <Icon type='question-circle'/>&nbsp;{messages('expense-14.key219')/*未核对*/}({receiptList.length - checkedNumber})
      </span>
    )
  };

  render() {
    const { receiptList, afterClose } = this.props;
    const { visible } = this.state;
    return receiptList.length > 0 ? (
      <a
        onClick={this.toState({ visible: true })}
        className='slide-expense-report-detail-expense-invoice-summary'
      >
        <Icon type="appstore-o" />&nbsp;{messages('expense-14.key277')/*发票概览*/}
        <Modal
          destroyOnClose
          visible={visible}
          title={this.renderTitle()}
          onCancel={this.toState({ visible: false })}
          afterClose={afterClose}
          footer={null}
          className='slide-expense-report-detail-expense-invoice-summary-modal'
        >
          <SlideExpenseReportDetailExpenseInvoiceSummaryFrame
            receiptList={receiptList}
            onCheck={this.onCheck}
          />
        </Modal>
      </a>
    ) : null
  }

}

export default SlideExpenseReportDetailExpenseInvoiceSummary;
